package com.wanmait.movie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.wanmait.movie.entity.Admin;
import com.wanmait.movie.entity.Movie;
import com.wanmait.movie.entity.MovieTypes;
import com.wanmait.movie.entity.Participating;
import com.wanmait.movie.entity.VO.MovieDTO;
import com.wanmait.movie.entity.VO.ParticipatingDTO;
import com.wanmait.movie.esdao.MovieRepository;
import com.wanmait.movie.mapper.MovieMapper;
import com.wanmait.movie.mapper.MovieTypesMapper;
import com.wanmait.movie.service.MovieService;
import com.wanmait.movie.service.MovieTypesService;
import com.wanmait.movie.service.ParticipatingService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
@Transactional(rollbackFor = Exception.class)
public class MovieServiceImpl extends ServiceImpl<MovieMapper, Movie> implements MovieService{
    @Resource
    private MovieMapper movieMapper;
    @Resource
    private MovieTypesMapper movieTypesMapper;
    @Resource
    private MovieRepository movieRepository;
    @Resource
    private MovieTypesService movieTypesService;
    @Resource
    private ParticipatingService participatingService;

    @Override
    public boolean saveOrUpdate(MovieDTO entity, Admin admin) {
        Movie movie = new Movie();
        List<ParticipatingDTO> participatingList = entity.getParticipatingList();
        movie.setId(entity.getId())
                .setMovieName(entity.getMovieName()).setMoviePic(entity.getMoviePic())
                .setEndTime(entity.getEndTime()).setReleaseTime(entity.getReleaseTime())
                .setIntroduction(entity.getIntroduction()).setLanguage(entity.getLanguage())
                .setTime(entity.getTime()).setSource(entity.getSource()).setActorDirector(entity.getActorDirector())
                .setUpdateTime(new Date()).setUpdateAdminId(admin.getId());
        if (entity.getId()==null){
            movie.setInsertAdminId(admin.getId());
            movieMapper.save(movie);
            entity.getMovieTypeList().forEach(movieType ->{
                MovieTypes movieTypes = new MovieTypes();
                movieTypes.setMovieId(movie.getId()).setMovieTypeId(movieType);
                movieTypesService.save(movieTypes);
            });
            if (participatingList != null){
                participatingList.forEach(participatingDTO -> {
                    Participating participating = new Participating();
                    participating.setMovieId(movie.getId()).setActorId(participatingDTO.getActorId())
                            .setRole(participatingDTO.getRole()).setSort(participatingDTO.getSort())
                            .setIntroduce(participatingDTO.getIntroduce()).setInsertAdminId(admin.getId())
                            .setUpdateTime(new Date()).setUpdateAdminId(admin.getId());
                    participatingService.save(participating);
                });
            }
        }else{
            this.saveOrUpdate(movie);
            LambdaQueryWrapper<MovieTypes> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MovieTypes::getMovieId , entity.getId());
            movieTypesService.remove(queryWrapper);
            entity.getMovieTypeList().forEach(movieType ->{
                MovieTypes movieTypes = new MovieTypes();
                movieTypes.setMovieId(entity.getId()).setMovieTypeId(movieType);
                movieTypesService.save(movieTypes);
            });
            if (participatingList != null){
                LambdaQueryWrapper<Participating> queryWrapperParticipating = new LambdaQueryWrapper<>();
                queryWrapperParticipating.eq(Participating::getMovieId , entity.getId());
                participatingService.remove(queryWrapperParticipating);
                participatingList.forEach(participatingDTO -> {
                    Participating participating = new Participating();
                    participating.setMovieId(entity.getId()).setActorId(participatingDTO.getActorId())
                            .setRole(participatingDTO.getRole()).setSort(participatingDTO.getSort())
                            .setIntroduce(participatingDTO.getIntroduce()).setInsertAdminId(admin.getId())
                            .setUpdateTime(new Date()).setUpdateAdminId(admin.getId());
                    participatingService.save(participating);
                });
            }
        }
        return true;
    }

    @Override
    public Integer getMovieTime(Integer id) {
        return movieMapper.selectById(id).getTime();
    }

    @Override
    public List<Movie> getNewMovieList() {
        LambdaQueryWrapper<Movie> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .lt(Movie::getReleaseTime, new Date())
                .gt(Movie::getEndTime,new Date())
                .orderByDesc(Movie::getReleaseTime);
        List<Movie> movieList=movieMapper.selectList(queryWrapper);
        List<Movie> newMovieList = new ArrayList<>();
        if (movieList.size() > 8) {
            for (int i = 0; i < 8; i++) {
                newMovieList.add(movieList.get(i));
            }
        } else {
            return movieList;
        }
        return newMovieList;
    }

    @Override
    public List<Movie> getWantMovieList() {
        LambdaQueryWrapper<Movie> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .gt(Movie::getReleaseTime,new Date())
                .orderByDesc(Movie::getWant);
        List<Movie> movieList=movieMapper.selectList(queryWrapper);
        List<Movie> wantMovieList = new ArrayList<>();
        if (movieList.size() > 8) {
            for (int i = 0; i < 8; i++) {
                wantMovieList.add(movieList.get(i));
            }
        } else {
            return movieList;
        }
        return wantMovieList;
    }

    @Override
    public PageInfo<Movie> getESMovieList(int pageNum, int movieTypeId, String keyword) {
        List<Movie> moviePage = movieRepository.findAllByMovieNameLike(keyword);
        List<Integer> movieIdList = new ArrayList<>();
        moviePage.forEach(movie -> {
            movieIdList.add(movie.getId());
        });
        PageHelper.startPage(pageNum, 5);
        MPJLambdaWrapper<MovieTypes> wrapper = new MPJLambdaWrapper<>();
        if (movieTypeId != 0) {
            wrapper.selectAll(Movie.class).leftJoin(Movie.class, Movie::getId, MovieTypes::getMovieId).eq(MovieTypes::getMovieTypeId, movieTypeId).in(MovieTypes::getMovieId, movieIdList);
        }else{
            wrapper.selectAll(Movie.class).leftJoin(Movie.class, Movie::getId, MovieTypes::getMovieId).in(MovieTypes::getMovieId, movieIdList).distinct();
        }
        List<Movie> movieList = movieTypesMapper.selectJoinList(Movie.class,wrapper);
        return new PageInfo(movieList);
    }

    @Override
    public List<Movie> getMovieList() {
        LambdaQueryWrapper<Movie> queryWrapper = new LambdaQueryWrapper<>();
        return movieMapper.selectList(queryWrapper);
    }
    /**
     * select movie_types.movie,movie.*
     * leftjoin movie on movie.id = movietype.moiveid
     * wher
     * */
//    @Override
//    public PageInfo<Movie> getESMovieLists() {
//        MPJLambdaWrapper<MovieTypes> wrapper = new MPJLambdaWrapper<>();
//        wrapper.selectAll(Movie.class).leftJoin(Movie.class, Movie::getId, MovieTypes::getMovieId);
//        List<Movie> movieList=movieTypesMapper.selectJoinList(Movie.class,wrapper);
//        movieList.forEach(System.out::println);
//        return null;
//    }
}
